home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / suckmods.zip / SUCKMODS.ZIP / suck05 / src / teamplay.qc < prev    next >
Text File  |  1997-05-09  |  36KB  |  1,398 lines

  1. void(entity e, float chan, string samp, float vol, float atten) playsound;
  2. /* teamplay.qc
  3.  
  4.    From
  5.         The Comlete Enhanced Teamplay
  6.  
  7.    John Spickes -- jspickes@eng.umd.edu
  8.  
  9.     $Id: teamplay.qc 1.17 1996/08/17 16:52:45 jspickes Exp $
  10.  
  11.     $Log: teamplay.qc $
  12.     Revision 1.17  1996/08/17 16:52:45  jspickes
  13.     Fixed a problem with displaying the current team settings that could cause
  14.     the wrong output when teamplay was negative.  Also added code to indicate
  15.     when ID's silly teamplay code is being used.
  16.  
  17.     Revision 1.16  1996/08/17 00:41:52  jspickes
  18.     Turned off strict coop by default.
  19.     Fixed a bug that could have caused strange behavior if TEAM_COLOR* was
  20.     set to -2.
  21.  
  22.     Revision 1.15  1996/08/17 00:34:17  jspickes
  23.     Added instructions on drop-item use in current settings output.
  24.     Fixed a problem that would allow you to drop lots of backpacks with
  25.     nothing in them.
  26.  
  27. */
  28.  
  29. /** Defs **/
  30.  
  31. /** MODIFIABLE CONSTANTS **/
  32.  
  33. float TEAM_DEFAULT_PENALTY =    1;      // Default frag penalty
  34. float TEAM_STRICT_COOP =    0;    // Strict Coop
  35.  
  36. // Allowed team colors
  37. // -1 indicates no color
  38.  
  39. float TEAM_COLOR1       =       4;
  40. float TEAM_COLOR2       =       13;
  41. float TEAM_COLOR3       =       -1;
  42. float TEAM_COLOR4       =       -1;
  43.  
  44. /** End of MODIFIABLE CONSTANTS **/
  45.  
  46. // Globals
  47.  
  48. entity team1_lastspawn;
  49. entity team2_lastspawn;
  50. float nextteamupdtime;
  51.  
  52. // Teamplay bitfield entries
  53.  
  54. float TEAM_HEALTH_PROTECT =     1;      // No health damage from friendly fire
  55. float TEAM_ARMOR_PROTECT =      2;      // No armor damage from friendly fire
  56. float TEAM_ATTACKER_DAMAGE =    4;      // Attacker takes damage from hitting teammates
  57. float TEAM_FRAG_PENALTY =       8;      // One frag penalty for killing teammate
  58. float TEAM_DEATH_PENALTY =      16;     // Die when you kill a teammate.
  59. float TEAM_LOCK_COLORS =        32;     // Allow only team colors
  60. float TEAM_STATIC_TEAMS =       64;     // Don't allow players to switch teams
  61. float TEAM_DROP_ITEMS =     128;    // Allow players to drop packs and 
  62. float TEAM_CAPTURE_FLAG =    256;    // Play capture the flag
  63. float TEAM_CAPTURE_CUSTOM =     512;    // custom models
  64.  
  65. // Teamplay options new to SuckMods are below
  66. float TEAM_CAPTURE_UNIF =     1024;   // Uniform team scores (Suck)
  67. float TEAM_GROUP_POWER  =     2048;    // Group power (Suck)
  68. float TEAM_RUNES_SETS    =     4096;    // Use rune sets (Suck)
  69. float TEAM_RUNES_GROUP    =    8192;   // One group of runes (Suck)
  70. float TEAM_RUNES_RANDOM =    16384;  // Choose runes randomly (Suck)
  71. float TEAM_RUNES_YGGDRASIL =    32768;  // War of the pantheons (Suck)
  72. float TEAM_DROP_RUNES    =     65536;  // Allow rune dropping (Suck)
  73. float TEAM_STATUS_BAR    =     131072;  // Status bar on or off (Suck)
  74. float TEAM_FORWARD_PLAYERS=     262144; // Forward players if we're full (Suck)
  75. float TEAM_CUSTOM_RUNES =     524288; // Use custom rune models      
  76.  
  77. // Suck: These are the scores for the uniform scoring system
  78. float TEAM_UNIFORM_CAPTURE_BONUS = 80;
  79. float TEAM_UNIFORM_RECOVERY_BONUS = 8;
  80. float TEAM_UNIFORM_CARRIER_BONUS = 16;
  81.  
  82. float TEAM_CAPTURE_CAPTURE_BONUS = 15; // what you get for capture
  83. float TEAM_CAPTURE_TEAM_BONUS = 10; // what your team gets for capture
  84. float TEAM_CAPTURE_RECOVERY_BONUS = 1; // what you get for recovery
  85. float TEAM_CAPTURE_FLAG_BONUS = 0; // what you get for picking up enemy flag
  86. float TEAM_CAPTURE_FRAG_CARRIER_BONUS = 2; // what you get for fragging
  87.     //enemy flag carrier
  88.  
  89. // Prototypes
  90. float() W_BestWeapon;
  91. void() W_SetCurrentAmmo;
  92. void() bound_other_ammo;
  93. void(float o, float n) Deathmatch_Weapon;
  94. void() BackpackTouch;
  95. //void()    flag_wave1;
  96. void()    regen_flag;
  97. void(entity p, string st) clientmsg;
  98.  
  99. // Return a name for the color of a team
  100. string(float Team) GetTeamColor =
  101. {
  102.     if(Team == 0) return("Blue");
  103.     else if(Team == 1) return("Steel blue");
  104.     else if(Team == 2) return("Brown");
  105.     else if(Team == 3) return("Baby blue");
  106.     else if(Team == 4) return("Green");
  107.     else if(Team == 5) return("Red");
  108.     else if(Team == 6) return("Olive");
  109.     else if(Team == 7) return("Orange");
  110.     else if(Team == 8) return("Peach");
  111.     else if(Team == 9) return("Purple");
  112.     else if(Team == 10) return("Majenta");
  113.     else if(Team == 11) return("Grey");
  114.     else if(Team == 12) return("Aqua");
  115.     else if(Team == 13) return("Yellow");
  116.     else if(Team == 14) return("Blue");
  117.     return "Unknown";
  118. };
  119.  
  120.  
  121. /*
  122. ================
  123. TeamPrintSettings
  124.  
  125. Print out current teamplay options
  126. ================
  127. */
  128.  
  129.  
  130. void() TeamPrintSettings =
  131. {
  132.     local string s;
  133.     
  134.     sprint(self,"The following Teamplay options are set:\n");
  135.     
  136.     if(teamplay < 0)
  137.     {
  138.         sprint(self, "Frag penalty manually set to ");
  139.         s = ftos(teamplay);
  140.         sprint(self, s);
  141.         sprint(self, "\n");
  142.         return;
  143.     }
  144.     
  145.     if(!teamplay) 
  146.     {
  147.         sprint(self, "None\n");
  148.         return;
  149.     }
  150.     
  151.     if(1 == teamplay)
  152.     {
  153.         sprint(self, "ID's original teamplay 1\n");
  154.         return;
  155.     }
  156.     
  157.     if(teamplay & TEAM_HEALTH_PROTECT)
  158.         sprint(self, "Health-Protect ");
  159.     
  160.     if(teamplay & TEAM_ARMOR_PROTECT)
  161.         sprint(self, "Armor-Protect ");
  162.         
  163.     if(teamplay & TEAM_ATTACKER_DAMAGE)
  164.         sprint(self, "Mirror-Damage ");
  165.         
  166.     if(teamplay & TEAM_FRAG_PENALTY)
  167.         sprint(self, "Frag-Penalty ");
  168.         
  169.     if(teamplay & TEAM_DEATH_PENALTY)
  170.         sprint(self, "Death-Penalty ");
  171.         
  172.     if(teamplay & TEAM_LOCK_COLORS)
  173.         sprint(self, "Lock-Colors ");
  174.         
  175.     if(teamplay & TEAM_STATIC_TEAMS)
  176.         sprint(self, "Static-Teams ");
  177.         
  178.     if(teamplay & TEAM_DROP_ITEMS)
  179.         sprint(self, "Drop-Items (Backpack Impulse 20, Weapon Impulse 21) ");
  180.         
  181.     if(teamplay & TEAM_CAPTURE_FLAG)
  182.         sprint(self, "Capture-The-Flag ");
  183.  
  184.     sprint(self, "\n");
  185. };
  186.  
  187. /*
  188. ================
  189. TeamArmorDam
  190.  
  191. Return TRUE if the target's armor can take damage from this attacker.
  192. ================
  193. */
  194.  
  195. float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam =
  196. {
  197.         if( teamplay < 0 )
  198.                 return TRUE;
  199.         if( (teamplay & TEAM_ARMOR_PROTECT) && 
  200.             (attacker.lastteam == targ.lastteam) && 
  201.             (attacker != targ) && (targ.lastteam > 0) )
  202.         {
  203.                 // Armor is protected
  204.                 return FALSE;
  205.         }
  206.         return TRUE;
  207. };
  208.  
  209. /*
  210. ================
  211. TeamHealthDam
  212.  
  213. Return TRUE if the target can take health damage from this attacker.
  214. ================
  215. */
  216.  
  217. float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam =
  218. {
  219.         if( teamplay < 0 )
  220.         {
  221.                 return TRUE;
  222.         }
  223.         if( (attacker.lastteam == targ.lastteam) && 
  224.             (attacker != targ) && (targ.lastteam > 0) )
  225.         {
  226.                 // Attacker and target are on the same team.
  227.                 if( teamplay & TEAM_ATTACKER_DAMAGE )
  228.                 {
  229.                         // Damage applied to teammate.
  230.                         T_Damage(attacker, inflictor, attacker, damage);
  231.                 }
  232.                 if( teamplay & TEAM_HEALTH_PROTECT )
  233.                 {
  234.                         // Health is protected
  235.                         return FALSE;
  236.                 }
  237.         }
  238.         return TRUE;
  239. };
  240.  
  241. /*
  242. ================
  243. TeamPFrags
  244.  
  245. Return the number of frags we should penalize attacker for killing targ.
  246. ================
  247. */
  248.  
  249. float(entity targ, entity attacker) TeamPFrags =
  250. {
  251.         if( teamplay < 0 )
  252.                 return (-1 * teamplay);
  253.         if( (targ.lastteam > 0) && (targ != attacker) && (targ.lastteam ==
  254.             attacker.lastteam) )
  255.         {
  256.                 // targ and attacker are on the same team
  257.                 if( teamplay < 0 )
  258.                 {
  259.                         // teamplay indicates frag penalty
  260.                         return ( -1 * teamplay );
  261.                 }
  262.                 if( teamplay & TEAM_FRAG_PENALTY )
  263.                 {
  264.                         // default penalty
  265.                         return TEAM_DEFAULT_PENALTY;
  266.                 }
  267.         }
  268.         // No frag penalty
  269.         return 0;
  270. };
  271.  
  272. /*
  273. ================
  274. TeamFragPenalty
  275.  
  276. If attacker should be penalized for killing targ, penalize attacker
  277. and return TRUE.
  278. ================
  279. */
  280.  
  281. float(entity targ, entity attacker) TeamFragPenalty =
  282. {
  283.         local float f;
  284.  
  285.         f = TeamPFrags(targ, attacker);
  286.  
  287.         if( f )
  288.         {
  289.                 // We should penalize some frags.
  290.                 attacker.frags = attacker.frags - f;
  291.                 return TRUE;
  292.         }
  293.         // No penalty
  294.         return FALSE;
  295. };
  296.  
  297. /*
  298. =================
  299. TeamDeathPenalty
  300.  
  301. If attacker should be killed for killing targ, kill attacker and
  302. add a frag to offset the one attacker will lose for killing himself.
  303. */
  304.  
  305. void(entity targ, entity attacker) TeamDeathPenalty =
  306. {
  307.         //Don't kill anyone if teamplay is negative.
  308.         if ( teamplay < 0 )
  309.                 return;
  310.  
  311.         if ( (teamplay & TEAM_DEATH_PENALTY) && (targ.lastteam > 0) &&
  312.             (attacker != targ) && (attacker.lastteam == targ.lastteam) )
  313.         {
  314.                 //We should kill the attacker.
  315.                 T_Damage(attacker,attacker,attacker,1000);
  316.                 //Add a frag to offset the self-kill penalty.
  317.                 attacker.frags = attacker.frags + 1;
  318.         }
  319. };
  320.  
  321. /*
  322. ==================
  323. TeamColorIsLegal
  324.  
  325. Return TRUE if the indicated color is legal
  326. ==================
  327. */
  328. float(float color) TeamColorIsLegal =
  329. {
  330.         // All colors are legal if teamplay is negative.
  331.         if( teamplay < 0 )
  332.                 return TRUE;
  333.         // All colors are legal if TEAM_LOCK_COLORS is off.
  334.         if( !(teamplay & TEAM_LOCK_COLORS) )
  335.                 return TRUE;
  336.         if( (color == TEAM_COLOR1) && (TEAM_COLOR1 >= 0) )
  337.                 return TRUE;
  338.         if( (color == TEAM_COLOR2) && (TEAM_COLOR2 >= 0) )
  339.                 return TRUE;
  340.         if( (color == TEAM_COLOR3) && (TEAM_COLOR3 >= 0) )
  341.                 return TRUE;
  342.         if( (color == TEAM_COLOR4) && (TEAM_COLOR4 >= 0) )
  343.                 return TRUE;
  344. };
  345.  
  346. /*
  347. ==================
  348. TeamCheckTeam
  349.  
  350. Check if the team self is on is legal, and put self in a legal team if not.
  351. ==================
  352. */
  353. void() TeamCheckTeam =
  354. {
  355.     local float TEAM1;
  356.     local float TEAM2;
  357.     local float TEAM3;
  358.     local float TEAM4;
  359.  
  360.     local float newcolor;
  361.     local float t;
  362.  
  363.     local entity p;
  364.  
  365.     local string n; 
  366.  
  367.     if( self.lastteam >= 0 )
  368.     {
  369.             if(TeamColorIsLegal(self.team - 1)) {
  370.                 self.lastteam = self.team;
  371.                 return;
  372.             }
  373.     }
  374.  
  375.     // Assign the player to a team.
  376.  
  377.     // Sum the players on all the teams.
  378.  
  379.     TEAM1 = 0;
  380.     TEAM2 = 0;
  381.     TEAM3 = 0;
  382.     TEAM4 = 0;
  383.  
  384.  
  385.     p = find (world, classname, "player");
  386.  
  387.     while(p)
  388.     {
  389.         if (p != self) {
  390.             if( (TEAM_COLOR1 >= 0) && (p.team == (TEAM_COLOR1 +1)) )
  391.                     TEAM1 = TEAM1 + 1;
  392.             if( (TEAM_COLOR2 >= 0) && (p.team == (TEAM_COLOR2 +1)) )
  393.                     TEAM2 = TEAM2 + 1;
  394.             if( (TEAM_COLOR3 >= 0) && (p.team == (TEAM_COLOR3 +1)) )
  395.                     TEAM3 = TEAM3 + 1;
  396.             if( (TEAM_COLOR4 >= 0) && (p.team == (TEAM_COLOR4 +1)) )
  397.                     TEAM4 = TEAM4 + 1;
  398.         }
  399.         p = find(p, classname, "player");
  400.     }
  401.  
  402.     // Find the team with the least players.
  403.     newcolor = TEAM_COLOR1;
  404.     t = TEAM1;
  405.  
  406.  
  407.         if ( (TEAM_COLOR2 >= 0) && ((TEAM2 < t) || (TEAM2 == t && random() < 0.5))) {
  408.                         newcolor = TEAM_COLOR2;
  409.                         t = TEAM2;
  410.         }
  411.  
  412.         if ( (TEAM_COLOR3 >= 0) && ((TEAM3 < t) || (TEAM2 == t && random() < 0.5))) {
  413.                         newcolor = TEAM_COLOR3;
  414.                         t = TEAM3;
  415.         }
  416.  
  417.         if ( (TEAM_COLOR4 >= 0) && ((TEAM4 < t) || (TEAM2 == t && random() < 0.5))) {
  418.                         newcolor = TEAM_COLOR4;
  419.                         t = TEAM4;
  420.         }
  421.  
  422.     // Put the player on a the new team.
  423.  
  424.     n = ftos(newcolor);
  425.     stuffcmd(self, "color ");
  426.     stuffcmd(self, n);
  427.     stuffcmd(self, "\n");
  428.  
  429.     sprint(self, "You have been assigned color ");
  430.     sprint(self, n);
  431.     sprint(self, "\nLegal colors are:");
  432.     if(TEAM_COLOR1 >= 0)
  433.     {
  434.             n = ftos(TEAM_COLOR1);
  435.             sprint(self, " ");
  436.             sprint(self, n);
  437.     }
  438.     if(TEAM_COLOR2 >= 0)
  439.     {
  440.             n = ftos(TEAM_COLOR2);
  441.             sprint(self, " ");
  442.             sprint(self, n);
  443.     }
  444.     if(TEAM_COLOR3 >= 0)
  445.     {
  446.             n = ftos(TEAM_COLOR3);
  447.             sprint(self, " ");
  448.             sprint(self, n);
  449.     }
  450.     if(TEAM_COLOR4 >= 0)
  451.     {
  452.             n = ftos(TEAM_COLOR4);
  453.             sprint(self, " ");
  454.             sprint(self, n);
  455.     }
  456.  
  457.     sprint(self, "\n");
  458.  
  459.     self.lastteam = newcolor + 1;      // Remember what team we're on
  460.     self.team = newcolor + 1;
  461. };
  462.  
  463. /*
  464. ===============
  465. TeamCheckLock
  466.  
  467. Check for team changing and perform whatever actions are neccessary.
  468. ===============
  469. */
  470. void() TeamCheckLock =
  471. {
  472.         local   float   n;
  473.         local   string  s;
  474.     local float r;
  475.  
  476.         // Don't do anything if teamplay is negative
  477.         if ( teamplay < 0 )
  478.                 return;
  479.  
  480.         if (self.player_flag & TEAM_STUFF_COLOR) {
  481.             self.player_flag = self.player_flag - TEAM_STUFF_COLOR;
  482.             r=4;
  483.             while ((r==4) || (r==13))
  484.             {
  485.                 r=random();
  486.                 r=r*13;
  487.                 r=rint(r);
  488.             }
  489.             stuffcmd(self, "color ");
  490.             s=ftos(r);
  491.             stuffcmd(self, s);
  492.             n = self.lastteam - 1;
  493.             s = ftos(n);
  494.             stuffcmd(self, " ")    ;
  495.             stuffcmd(self, s);
  496.             stuffcmd(self, "\n");
  497.             return;
  498.         }
  499.  
  500.         if ( !TeamColorIsLegal(self.team - 1) && (self.team == self.lastteam)) {
  501.             self.lastteam = -1;
  502.         }
  503.  
  504.         // Check to see if the player has changed colors
  505.         if (self.team != self.lastteam)
  506.         {
  507.                 // Player has changed colors
  508.  
  509.                 // If teams are static and we've been on some team already,
  510.                 // put us back on the team we were on.
  511.  
  512.                 if ( (teamplay & TEAM_STATIC_TEAMS) && (self.lastteam >= 0) )
  513.                 {
  514.                         if ( TeamColorIsLegal(self.lastteam - 1) )
  515.                         {
  516.                                 // changing teams sucks, kill him
  517.  
  518.                                 // if he has tried to change teams several
  519.                                 // times, kick him off the server.
  520.                                 if (self.suicide_count > 3) {
  521.                                     sprint(self, "You were told you can't change teams.\nGo play color games somewhere else.\n");
  522.                                     stuffcmd(self, "disconnect\n");
  523.                                     bprint(self.netname);
  524.                                     bprint(" has bad color sense\n");
  525.                                 }
  526.                                 // case base respawn
  527.                                 if (self.killed != 1)
  528.                                     self.killed = 2;
  529.                                 self.frags=0;
  530.                                 T_Damage(self,self,self,10000);  // Kill the player
  531.                                 // trying to change teams counts as a suicide
  532.                                 self.suicide_count = self.suicide_count + 1;
  533.  
  534.                                 sprint(self, "You cannot change teams.\n");
  535.                                 stuffcmd(self, "color ");
  536.                                 n = self.lastteam - 1;
  537.                                 s = ftos(n);
  538.                                 stuffcmd(self, s);
  539.                                 stuffcmd(self, "\n");
  540.                                 self.team = self.lastteam;
  541.                                 return;
  542.                         }
  543.                         else {
  544.                                 // If we're on an illegal team, force a change.
  545.                                 self.lastteam = -50;
  546.                         }
  547.                 }
  548.  
  549.                 // If teamlock is turned off, don't do anything more.
  550.                 if ( !(teamplay & TEAM_LOCK_COLORS) )
  551.                 {
  552.                         self.lastteam = self.team;
  553.                         return;
  554.                 }
  555.  
  556.                 if(self.lastteam > 0) {
  557.                     // case base respawn
  558.                     if (self.killed != 1)
  559.                         self.killed = 2;
  560.                     T_Damage(self,self,self,1000);  // Kill the player
  561.                 }
  562.                 self.frags = 0;                 // Zero out frags
  563.         self.score = 0;
  564.                 TeamCheckTeam();
  565.         }
  566. };
  567.  
  568. /*
  569. =======================
  570. TossBackPack
  571.  
  572. Original idea by Vhold
  573. Rewritten by John Spickes
  574.  
  575. Toss out a backpack containing some ammo from your current weapon,
  576. and any weapons you don't have.
  577. =======================
  578. */
  579. void() TossBackpack =
  580. {
  581.     local entity     item;
  582.  
  583.     // If we don't have any ammo, return
  584.     if(self.currentammo <= 0)
  585.         return;
  586.  
  587.     item = spawn();
  588.  
  589.     // See if you have the Shotgun or Super Shotgun on
  590.         if ( (self.weapon == IT_SHOTGUN) || (self.weapon == IT_SUPER_SHOTGUN) )
  591.     {
  592.         if( self.ammo_shells >= 20 ) {
  593.             item.ammo_shells = 20;
  594.             self.ammo_shells = self.ammo_shells - 20;
  595.         }
  596.         else
  597.         {
  598.             item.ammo_shells = self.ammo_shells;
  599.             self.ammo_shells = 0;
  600.         }
  601.     }        
  602.     
  603.     // See if you have neither the Shotgun or Super Shotgun
  604.         if ( !(self.items & IT_SHOTGUN) && !(self.items & IT_SUPER_SHOTGUN) )
  605.     {
  606.         if( self.ammo_shells >= 20 ) {
  607.             item.ammo_shells = 20;
  608.             self.ammo_shells = self.ammo_shells - 20;
  609.         }
  610.         else
  611.         {
  612.             item.ammo_shells = self.ammo_shells;
  613.             self.ammo_shells = 0;
  614.         }
  615.     }        
  616.     
  617.     // See if we are using a nailgun
  618.         if ( (self.weapon == IT_NAILGUN) || (self.weapon == IT_SUPER_NAILGUN) )
  619.     {
  620.         if( self.ammo_nails >= 20 )
  621.         {
  622.             item.ammo_nails = 20;
  623.             self.ammo_nails = self.ammo_nails - 20;
  624.         }
  625.         else
  626.         {
  627.             item.ammo_nails = self.ammo_nails;
  628.             self.ammo_nails = 0;
  629.         }
  630.     }    
  631.     // Check to see if we have neither nailgun
  632.         if ( !(self.items & IT_NAILGUN) && !(self.items & IT_SUPER_NAILGUN) )
  633.     {
  634.         if( self.ammo_nails >= 20 )
  635.         {
  636.             item.ammo_nails = 20;
  637.             self.ammo_nails = self.ammo_nails - 20;
  638.         }
  639.         else
  640.         {
  641.             item.ammo_nails = self.ammo_nails;
  642.             self.ammo_nails = 0;
  643.         }
  644.     }    
  645.     
  646.     // See if we are using a grenade or rocket launcher
  647.         if ( (self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_ROCKET_LAUNCHER) )
  648.     {
  649.         if( self.ammo_rockets >= 10 )
  650.         {
  651.             item.ammo_rockets = 10;
  652.             self.ammo_rockets = self.ammo_rockets - 10;
  653.         }
  654.         else
  655.         {
  656.             item.ammo_rockets = self.ammo_rockets;
  657.             self.ammo_rockets = 0;
  658.         }
  659.     }
  660.     // See if we have neither the Grenade or rocket launcher
  661.         if ( !(self.items & IT_GRENADE_LAUNCHER) && !(self.items & IT_ROCKET_LAUNCHER) )
  662.     {
  663.         if( self.ammo_rockets >= 10 )
  664.         {
  665.             item.ammo_rockets = 10;
  666.             self.ammo_rockets = self.ammo_rockets - 10;
  667.         }
  668.         else
  669.         {
  670.             item.ammo_rockets = self.ammo_rockets;
  671.             self.ammo_rockets = 0;
  672.         }
  673.     }
  674.  
  675.     // See if we're using the lightning gun
  676.     if ( self.weapon == IT_LIGHTNING )
  677.     {
  678.         if ((self.rune_num == ITEM_RUNE_THOR) ||
  679.         (self.rune_num == ITEM_RUNE_POSEIDON))
  680.             return;
  681.         if( self.ammo_cells >= 20 )
  682.         {
  683.             item.ammo_cells = 20;
  684.             self.ammo_cells = self.ammo_cells - 20;
  685.         }
  686.         else
  687.         {
  688.             item.ammo_cells = self.ammo_cells;
  689.             self.ammo_cells = 0;
  690.         }
  691.     }
  692.     // see if we don't have the lightning gun
  693.         if ( !(self.items & IT_LIGHTNING) )
  694.     {    
  695.         if( self.ammo_cells >= 20 )
  696.         {
  697.             item.ammo_cells = 20;
  698.             self.ammo_cells = self.ammo_cells - 20;
  699.         }
  700.         else
  701.         {
  702.             item.ammo_cells = self.ammo_cells;
  703.             self.ammo_cells = 0;
  704.         }
  705.     }
  706.      
  707.     item.owner = self;
  708.     makevectors(self.v_angle);
  709.  
  710.     setorigin(item, self.origin + '0 0 16');
  711.     item.velocity = aim(self, 1000);
  712.     item.velocity = item.velocity * 500;
  713.     item.flags = FL_ITEM;
  714.     item.solid = SOLID_TRIGGER;
  715.     item.movetype = MOVETYPE_BOUNCE;
  716.  
  717.     setmodel (item, "progs/backpack.mdl");
  718.     setsize(item, '-16 -16 0', '16 16 56');
  719.     item.touch = BackpackTouch;
  720.     item.nextthink = time + 120;    // remove after 2 minutes
  721.     item.think = SUB_Remove;
  722.  
  723.     W_SetCurrentAmmo();
  724.  
  725. };
  726.  
  727. void() Team_weapon_touch =
  728. {
  729.     local    float    hadammo, best, new, old;
  730.     local entity stemp;
  731.  
  732.     if (!(other.flags & FL_CLIENT))
  733.         return;
  734.     // Don't let the owner pick up his own weapon for a second.
  735.     if ( (other == self.owner) && ( (self.nextthink - time) > 119 ) )
  736.         return;
  737.  
  738. // if the player was using his best weapon, change up to the new one if better        
  739.     stemp = self;
  740.     self = other;
  741.     best = W_BestWeapon();
  742.     self = stemp;
  743.  
  744.     if (self.classname == "weapon_nailgun")
  745.     {
  746.         hadammo = other.ammo_nails;            
  747.         new = IT_NAILGUN;
  748.     }
  749.     else if (self.classname == "weapon_supernailgun")
  750.     {
  751.         hadammo = other.ammo_rockets;            
  752.         new = IT_SUPER_NAILGUN;
  753.     }
  754.     else if (self.classname == "weapon_supershotgun")
  755.     {
  756.         hadammo = other.ammo_rockets;            
  757.         new = IT_SUPER_SHOTGUN;
  758.     }
  759.     else if (self.classname == "weapon_rocketlauncher")
  760.     {
  761.         hadammo = other.ammo_rockets;            
  762.         new = IT_ROCKET_LAUNCHER;
  763.     }
  764.     else if (self.classname == "weapon_grenadelauncher")
  765.     {
  766.         hadammo = other.ammo_rockets;            
  767.         new = IT_GRENADE_LAUNCHER;
  768.     }
  769.     else if (self.classname == "weapon_lightning")
  770.     {
  771.         hadammo = other.ammo_rockets;            
  772.         new = IT_LIGHTNING;
  773.     }
  774.     else
  775.         objerror ("Team_weapon_touch: unknown classname");
  776.  
  777.     sprint (other, "You got the ");
  778.     sprint (other, self.netname);
  779.     sprint (other, "\n");
  780. // weapon touch sound
  781.     playsound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  782.     stuffcmd (other, "bf\n");
  783.  
  784.     bound_other_ammo ();
  785.  
  786. // change to the weapon
  787.     old = other.items;
  788.     other.items = other.items | new;
  789.     
  790.     remove(self);
  791.     self = other;
  792.  
  793.     if (!deathmatch)
  794.         self.weapon = new;
  795.     else
  796.         Deathmatch_Weapon (old, new);
  797.  
  798.     W_SetCurrentAmmo();
  799.  
  800.     activator = other;
  801.     SUB_UseTargets();                // fire all targets / killtargets
  802. };
  803.         
  804. void() TossWeapon =
  805. {
  806.     local entity item;
  807.     
  808.     if (deathmatch != 2)
  809.         return;  // only in deathmatch 2
  810.  
  811.     if (((self.rune_num == ITEM_RUNE_THOR) ||
  812.         (self.rune_num == ITEM_RUNE_POSEIDON)) &&
  813.         (self.weapon == IT_LIGHTNING))
  814.         return;
  815.  
  816.     if((self.weapon == IT_AXE) || (self.weapon == IT_SHOTGUN) ||
  817.         (self.weapon == IT_HOOK))
  818.         return;
  819.         
  820.     item = spawn();
  821.     item.owner = self;
  822.     makevectors(self.v_angle);
  823.  
  824.     setorigin(item, self.origin + '0 0 16');
  825.     item.velocity = aim(self, 1000);
  826.     item.velocity = item.velocity * 500;
  827.     item.flags = FL_ITEM;
  828.     item.solid = SOLID_TRIGGER;
  829.     item.movetype = MOVETYPE_BOUNCE;
  830.     
  831.     if(self.weapon == IT_SUPER_SHOTGUN)
  832.     {
  833.         setmodel (item, "progs/g_shot.mdl");
  834.         item.weapon = IT_SUPER_SHOTGUN;
  835.         item.netname = "Double-barrelled Shotgun";
  836.         item.classname = "weapon_supershotgun";
  837.         self.items = self.items - IT_SUPER_SHOTGUN;
  838.     }
  839.  
  840.     if( self.weapon == IT_NAILGUN )
  841.     {
  842.         setmodel (item, "progs/g_nail.mdl");
  843.         item.weapon = IT_NAILGUN;
  844.         item.netname = "nailgun";
  845.         item.classname = "weapon_nailgun";
  846.         self.items = self.items - IT_NAILGUN;
  847.     }
  848.         
  849.     if( self.weapon == IT_SUPER_NAILGUN)
  850.     {
  851.         setmodel (item, "progs/g_nail2.mdl");
  852.         item.weapon = IT_SUPER_NAILGUN;
  853.         item.netname = "Super Nailgun";
  854.         item.classname = "weapon_supernailgun";
  855.         self.items = self.items - IT_SUPER_NAILGUN;
  856.     }
  857.     
  858.     if( self.weapon == IT_GRENADE_LAUNCHER)
  859.     {
  860.         setmodel (item, "progs/g_rock.mdl");
  861.         item.weapon = 3;
  862.         item.netname = "Grenade Launcher";
  863.         item.classname = "weapon_grenadelauncher";
  864.         self.items = self.items - IT_GRENADE_LAUNCHER;
  865.     }
  866.     
  867.     if( self.weapon == IT_ROCKET_LAUNCHER )
  868.     {
  869.         setmodel (item, "progs/g_rock2.mdl");
  870.         item.weapon = 3;
  871.         item.netname = "Rocket Launcher";
  872.         item.classname = "weapon_rocketlauncher";
  873.         self.items = self.items - IT_ROCKET_LAUNCHER;
  874.     }
  875.     
  876.     if( self.weapon == IT_LIGHTNING )
  877.     {
  878.         setmodel (item, "progs/g_light.mdl");
  879.         item.weapon = 3;
  880.         item.netname = "Thunderbolt";
  881.         item.classname = "weapon_lightning";
  882.         self.items = self.items - IT_LIGHTNING;
  883.     }
  884.     setsize(item, '-16 -16 0', '16 16 56');
  885.     item.touch = Team_weapon_touch;
  886.     item.think = SUB_Remove;
  887.     item.nextthink = time + 120;
  888.     
  889.     self.weapon = W_BestWeapon();
  890.     W_SetCurrentAmmo();
  891. };
  892.  
  893. void() SilentKill;
  894.  
  895. void() TeamCaptureRegenFlags =
  896. {
  897.     local entity f;
  898.     
  899.     self = find(world, classname, "item_flag_team1");
  900.     if (self != world) 
  901.         regen_flag();
  902.     self = find(world, classname, "item_flag_team2");
  903.     if (self != world) 
  904.         regen_flag();
  905. };
  906.  
  907. void() TeamCaptureFlagSanityCheck =
  908. {
  909.     local entity p;
  910.  
  911.     // Ok, a flag must be in one of three states
  912.     // 1. At home base (though we shouldn't be called in that case)
  913.     // 2. On enemy player
  914.     // 3. A copy is sitting around somewhere, waiting to be picked up
  915.  
  916.     // at home base?
  917.     if (self.model != string_null) {
  918.         self.think = TeamCaptureFlagSanityCheck;
  919.         self.nextthink = time + 30;
  920.         return; // its at home, no prob
  921.     }
  922.     
  923.     // on enemy player?
  924.     p = find(world, classname, "player");
  925.     while (p != world) {
  926.         if ((p.team != self.team) && (p.player_flag & ITEM_ENEMY_FLAG)) {
  927.             self.think = TeamCaptureFlagSanityCheck;
  928.             self.nextthink = time + 30;
  929.             return; // enemy player has it
  930.         }
  931.         p = find(p, classname, "player");
  932.     }
  933.  
  934.     // copy sitting around somewhere
  935.     p = find(world, classname, "info_dropped_flag");
  936.     while (p != world) {
  937.         if (p.team == self.team) {
  938.             self.think = TeamCaptureFlagSanityCheck;
  939.             self.nextthink = time + 30;
  940.             return; // its out hanging around
  941.         }
  942.         p = find(p, classname, "info_dropped_flag");
  943.     }
  944.     // didn't find it, oh my
  945.     // regen this one
  946.     regen_flag();
  947. };
  948.  
  949. void() TeamCaptureFlagTouch =
  950. {
  951.     local entity p, oself;
  952.  
  953.     if (other.classname != "player")
  954.         return;
  955.     if (other.health <= 0)
  956.         return;
  957.  
  958.     if (other.team != other.lastteam)
  959.         return; // something is fishy, somebody is playing with colors
  960.  
  961.     if (self.team == other.team) {
  962.         // same team, if the flag is *not* at the base, return
  963.         // it to base.  we overload the 'cnt' field for this
  964.         if (self.cnt) {
  965.             // the flag is at home base.  if the player has the enemy
  966.             // flag, he's just won!
  967.  
  968.             if (other.player_flag & ITEM_ENEMY_FLAG) {
  969.                 bprint(other.netname);
  970.                 if (other.team == TEAM_COLOR1 + 1)
  971.                     bprint(" πß≡⌠⌡≥σΣ the ┬╠╒┼ flag!\n"); // blue
  972.                 else
  973.                     bprint(" πß≡⌠⌡≥σΣ the ╥┼─ flag!\n"); // red
  974.                 LogMsg(other, "FLAG-CAPTURE");
  975.                 other.items = other.items - (other.items & (IT_KEY1 | IT_KEY2));
  976.  
  977.                 if (cvar("teamplay") & TEAM_CAPTURE_CUSTOM)
  978.                     playsound (other, CHAN_VOICE, "misc/flagcap.wav", 1, ATTN_NONE);
  979.                 else
  980.                     playsound (other, CHAN_VOICE, "doors/meduse.wav", 1, ATTN_NONE);
  981.  
  982.                 // other gets another 10 frag bonus
  983.                 if (!(teamplay&TEAM_CAPTURE_UNIF))
  984.                     other.frags = other.frags + TEAM_CAPTURE_CAPTURE_BONUS;
  985.                 else
  986.                     other.frags = other.frags + TEAM_UNIFORM_CAPTURE_BONUS;
  987.                 other.score=other.score+TEAM_CAPTURE_CAPTURE_BONUS;                
  988.  
  989.                 // Ok, let's do the player loop, hand out the bonuses
  990.                 oself=self;
  991.                 p = find(world, classname, "player");
  992.                 while (p != world) {
  993.                     self = p;
  994.                     self.killed = 0;
  995.                     if ((self.team == other.team) && (self != other)) {
  996.                         if (!(teamplay&TEAM_CAPTURE_UNIF))
  997.                             self.frags = self.frags + TEAM_CAPTURE_TEAM_BONUS;
  998.                         else
  999.                             self.frags = self.frags + TEAM_UNIFORM_CAPTURE_BONUS;
  1000.                     }
  1001.                     if (self.team != other.team)
  1002.                         clientmsg(self, "Your flag was captured!\n");
  1003.                     else if (self.team == other.team)
  1004.                         clientmsg(self, "Your team captured the flag!\n");
  1005.                     self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
  1006. // ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1007. // client.qc:CheckDimLight
  1008. //                    self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1009.                     
  1010.                     p = find(p, classname, "player");
  1011.                 }
  1012.                 self=oself;
  1013.                 // respawn flags
  1014.                 TeamCaptureRegenFlags();
  1015.                 return;
  1016.             }
  1017.             return; // its at home base already
  1018.         }
  1019.         // hey, its not home.  return it by teleporting it back
  1020.         bprint(other.netname);
  1021.         if (other.team == TEAM_COLOR1 + 1)
  1022.             bprint(" ≥σ⌠⌡≥εσΣ the ╥┼─ flag!\n"); // red
  1023.         else
  1024.             bprint(" ≥σ⌠⌡≥εσΣ the ┬╠╒┼ flag!\n"); // blue
  1025.         LogMsg(other, "FLAG-RECOVERY");
  1026.         if (!(teamplay&TEAM_CAPTURE_UNIF))
  1027.             other.frags = other.frags + TEAM_CAPTURE_RECOVERY_BONUS;
  1028.         other.score=other.score+TEAM_CAPTURE_RECOVERY_BONUS;
  1029.  
  1030.         if (teamplay&TEAM_CAPTURE_UNIF) {
  1031.             oself=self;
  1032.             p = find(world, classname, "player");
  1033.             while (p != world) {
  1034.                 self = p;
  1035.                 self.killed = 0;
  1036.                 if (self.team == other.team)
  1037.                     self.frags = self.frags + TEAM_UNIFORM_RECOVERY_BONUS;
  1038.                 p = find(p, classname, "player");
  1039.             }
  1040.             self=oself;
  1041.             self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
  1042.         }
  1043.         playsound (other, CHAN_ITEM, self.noise1, 1, ATTN_NORM);
  1044.         remove(self); // oops it gone
  1045.         p = find(world, classname, "player");
  1046.         while (p != world) {
  1047.             if (p.team != other.team)
  1048.                 clientmsg(p, "Enemy flag has been returned to base!\n");
  1049.             else if (p.team == other.team)
  1050.                 clientmsg(p, "Your flag has been returned to base!\n");
  1051.             p = find(p, classname, "player");
  1052.         }
  1053.         if (other.team == TEAM_COLOR1 + 1) {
  1054.             self = find(world, classname, "item_flag_team1");
  1055.             if (self != world)  {
  1056.                 self.think = SUB_Null; // its at home, no need to think
  1057.                 regen_flag();
  1058.             }
  1059.         } else { // TEAM_COLOR2
  1060.             self = find(world, classname, "item_flag_team2");
  1061.             if (self != world) {
  1062.                 self.think = SUB_Null; // its at home, no need to think
  1063.                 regen_flag();
  1064.             }
  1065.         }
  1066.         return;
  1067.     }
  1068.  
  1069.     // hey, its not our flag, pick it up
  1070.     bprint(other.netname);
  1071.     if (other.team == TEAM_COLOR1 + 1)
  1072.         bprint(" τ∩⌠ the ┬╠╒┼ flag!\n"); // blue
  1073.     else
  1074.         bprint(" τ∩⌠ the ╥┼─ flag!\n"); // red
  1075.     LogMsg(other, "FLAG-PICKUP");
  1076.     if (TEAM_CAPTURE_FLAG_BONUS)
  1077.         other.frags = other.frags + TEAM_CAPTURE_FLAG_BONUS;
  1078.     other.score=other.score+TEAM_CAPTURE_FLAG_BONUS;    
  1079.     clientmsg(other, "┘╧╒ ╟╧╘ ╘╚┼ ┼╬┼═┘ ╞╠┴╟\n\n╥┼╘╒╥╬ ╘╧ ┬┴╙┼\n");
  1080.     playsound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1081.  
  1082.     other.player_flag = other.player_flag + ITEM_ENEMY_FLAG;
  1083.     other.items = other.items | self.items;
  1084.     // turn on the glow
  1085. // ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1086. // client.qc:CheckDimLight
  1087. //    other.effects = other.effects | EF_DIMLIGHT;
  1088.  
  1089.     // make the flag here disappear
  1090.     if (self.cnt) {
  1091.         // home base flags stay
  1092.         self.solid = SOLID_NOT;
  1093.         self.model = string_null;
  1094.         // set up sanity check
  1095.         self.think = TeamCaptureFlagSanityCheck;
  1096.         self.nextthink = time + 30; // 30 seconds pre check
  1097.     } else
  1098.         remove(self); // dropped flags recyclce
  1099.  
  1100.     p = find(world, classname, "player");
  1101.     while (p != world) {
  1102.         if (p != other) {
  1103.             if (p.team != other.team)
  1104.                 clientmsg(p, "Your flag has been taken!\n");
  1105.             else if (p.team == other.team)
  1106.                 clientmsg(p, "Your team has the enemy flag!\n");
  1107.         }
  1108.         p = find(p, classname, "player");
  1109.     }
  1110. };
  1111.  
  1112. void() TeamCaptureReturnFlag =
  1113. {
  1114.     local entity f, p;
  1115.  
  1116.     f = world;
  1117.     if (self.team == TEAM_COLOR1 + 1) {
  1118.         f = self;
  1119.         self = find(world, classname, "item_flag_team1");
  1120.         if (self != world) {
  1121.             self.think = SUB_Null; // its at home, no need to think
  1122.             regen_flag();
  1123.         }
  1124.     } else { // TEAM_COLOR2
  1125.         f = self;
  1126.         self = find(world, classname, "item_flag_team2");
  1127.         if (self != world) {
  1128.             self.think = SUB_Null; // its at home, no need to think
  1129.             regen_flag();
  1130.         }
  1131.     }
  1132.     if (f == world)
  1133.         return;
  1134.     p = find(world, classname, "player");
  1135.     while (p != world) {
  1136.         if (p.team != f.team)
  1137.             clientmsg(p, "Enemy flag has been returned to base!\n");
  1138.         else if (p.team == f.team)
  1139.             clientmsg(p, "Your flag has been returned to base!\n");
  1140.         p = find(p, classname, "player");
  1141.     }
  1142.     remove(f);
  1143. };
  1144.  
  1145. void() TeamCaptureDropFlag =
  1146. {
  1147.     local entity item, f, oself;
  1148.  
  1149.     if (!(self.player_flag & ITEM_ENEMY_FLAG))
  1150.         return;
  1151.  
  1152.     self.player_flag = self.player_flag - ITEM_ENEMY_FLAG;
  1153.  
  1154.     bprint(self.netname);
  1155.     if (self.lastteam == TEAM_COLOR1 + 1)
  1156.         bprint(" ∞∩≤⌠ the ┬╠╒┼ flag!\n"); // blue
  1157.     else
  1158.         bprint(" ∞∩≤⌠ the ╥┼─ flag!\n"); // red
  1159.     LogMsg(self, "FLAG-DROP");
  1160.  
  1161.     item = spawn();
  1162.     item.items = self.items & (IT_KEY1 | IT_KEY2);
  1163.     item.origin = self.origin - '0 0 24';
  1164.     item.cnt = 0; // it's NOT at home base
  1165.     //NOTE! We check lastteam here instead of team--this is because
  1166.     //in the mode where we change colors, we get killed
  1167.     if (self.lastteam == TEAM_COLOR1 + 1) {
  1168.         item.classname = "info_dropped_flag";
  1169.         item.team = TEAM_COLOR2 + 1;
  1170.         f = find(world, classname, "item_flag_team2");
  1171.         if (f != world) {
  1172.             setmodel(item, f.mdl);
  1173.             item.skin = f.skin;
  1174.             item.noise = f.noise;
  1175.             item.noise1 = f.noise1;
  1176.         } else {
  1177.             setmodel(item, "progs/lavaball.mdl");
  1178.             item.noise = "";
  1179.         }
  1180.     } else { // TEAM_COLOR2
  1181.         item.classname = "info_dropped_flag";
  1182.         item.team = TEAM_COLOR1 + 1;
  1183.         f = find(world, classname, "item_flag_team1");
  1184.         if (f != world) {
  1185.             setmodel(item, f.mdl);
  1186.             item.skin = f.skin;
  1187.             item.noise = f.noise;
  1188.             item.noise1 = f.noise1;
  1189.         } else {
  1190.             setmodel(item, "progs/lavaball.mdl");
  1191.             item.noise = "";
  1192.         }
  1193.     }
  1194.     item.velocity_z = 300;
  1195.     item.velocity_x = 0;
  1196.     item.velocity_y = 0;
  1197.     item.touch = TeamCaptureFlagTouch;
  1198.     item.flags = FL_ITEM;
  1199.     item.solid = SOLID_TRIGGER;
  1200.     item.movetype = MOVETYPE_TOSS;
  1201.     if (teamplay & TEAM_CAPTURE_CUSTOM)
  1202.         setsize(self, '-16 -16 0', '16 16 74');
  1203.     else
  1204.         setsize(item, '-16 -16 -24', '16 16 32');
  1205.     item.effects = item.effects | EF_DIMLIGHT; // make it glow
  1206.     oself = self;
  1207.     self = item;
  1208. //    flag_wave1(); // make it wave
  1209.     self = oself;
  1210.     // return the flag to base if no one picks it up for a while
  1211.     item.think = TeamCaptureReturnFlag;
  1212.     item.nextthink = time + 30;
  1213. };
  1214.  
  1215. // self is player
  1216. entity() TeamCaptureSpawn =
  1217. {
  1218.     
  1219.     if (!(teamplay & TEAM_CAPTURE_FLAG))
  1220.         return world;
  1221.  
  1222.     if (self.team == TEAM_COLOR1 + 1) {
  1223.         team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
  1224.         if (team1_lastspawn == world)
  1225.             team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
  1226.         return team1_lastspawn;
  1227.     } else { // if (self.team == TEAM_COLOR2 + 1)
  1228.         team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
  1229.         if (team2_lastspawn == world)
  1230.             team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
  1231.         return team2_lastspawn;
  1232.     }
  1233.     return world;
  1234. };
  1235.  
  1236. // ZOID -- total up team scores and set everyone's frag count to the team
  1237. // total
  1238. void() TeamScores =
  1239. {
  1240.     local float team1, team2, team3, team4;
  1241.     local entity p;
  1242.  
  1243.     if (teamscored || !teamplay)
  1244.         return; // already scored or not in team mode
  1245.  
  1246.     teamscored = 1;
  1247.  
  1248.     team1 = 0;
  1249.     team2 = 0;
  1250.     team3 = 0;
  1251.     team4 = 0;
  1252.  
  1253. dprint("TeamScores()\n");
  1254.     p = find(world, classname, "player");
  1255.     while (p != world) {
  1256. dprint("  Player=");
  1257. dprint(p.netname);
  1258. dprint(" Team=");
  1259. dprint(ftos(p.team));
  1260. dprint(" Frags=");
  1261. dprint(ftos(p.frags));
  1262. dprint("\n");
  1263.         if (p.team == TEAM_COLOR1 + 1)
  1264.             team1 = team1 + p.frags;
  1265.         else if (p.team == TEAM_COLOR2 + 1)
  1266.             team2 = team2 + p.frags;
  1267.         else if (p.team == TEAM_COLOR3 + 1)
  1268.             team3 = team3 + p.frags;
  1269.         else if (p.team == TEAM_COLOR4 + 1)
  1270.             team4 = team4 + p.frags;
  1271.         p = find(p, classname, "player");
  1272.     }
  1273. dprint(" Totals: team1=");
  1274. dprint(ftos(team1));
  1275. dprint(" team2=");
  1276. dprint(ftos(team2));
  1277. dprint("\n");
  1278.     p = find(world, classname, "player");
  1279.     while (p != world) {
  1280.         if (p.team == TEAM_COLOR1 + 1)
  1281.             p.frags = team1;
  1282.         else if (p.team == TEAM_COLOR2 + 1)
  1283.             p.frags = team2;
  1284.         else if (p.team == TEAM_COLOR3 + 1)
  1285.             p.frags = team3;
  1286.         else if (p.team == TEAM_COLOR4 + 1)
  1287.             p.frags = team4;
  1288.         p = find(p, classname, "player");
  1289.     }
  1290. };
  1291.  
  1292. /*
  1293.     From byron@caseware.com Wed Oct 16 18:57:44 1996
  1294.     Date: Wed, 16 Oct 1996 21:22:37 -0400
  1295.     From: Byron Long <byron@caseware.com>
  1296.     To: zoid@mindlink.net
  1297.     Subject: Team Status Command (source code included) :-)
  1298.  
  1299.     A co-worker of mine wondered if it was possible to add a function to
  1300.     your capture the flag code that would give a status report on an
  1301.     impulse. I think he may have mailed you, but I wrote a quick version
  1302.     myself, which your welcome to use if you like the feature (it offsets
  1303.     some of the problems with the chat capabilities in Quake so it seems
  1304.     like a worthwhile feature). Feel free to change it
  1305.     as necessary.
  1306. */
  1307.  
  1308. // *Capture The Flag - Status report by Wonko
  1309. void() TeamFlagStatusReport =
  1310. {
  1311.     local entity flag1, flag2, thief1, thief2, p;
  1312.  
  1313.     if (!(teamplay & TEAM_CAPTURE_FLAG)) {
  1314.         sprint(self, "Capture the Flag is not enabled.\n");
  1315.         return;
  1316.     }
  1317.  
  1318.     // Find the flags at home base
  1319.     flag1 = find (world,classname, "item_flag_team1");
  1320.     flag2 = find (world,classname, "item_flag_team2");
  1321.  
  1322.     // Find whether they are superceded by dropped flags
  1323.     if (flag1 != world && flag2 != world && 
  1324.         (flag1.model == string_null || flag2.model == string_null)) {
  1325.         p = find(world, classname, "info_dropped_flag");
  1326.         while (p != world) {
  1327.             if (p.team == TEAM_COLOR1 + 1) {
  1328.                 if (flag1.model == string_null) 
  1329.                     flag1 = p;
  1330.             }
  1331.             else {
  1332.                 if (flag2.model == string_null) 
  1333.                     flag2 = p;
  1334.             }
  1335.             p = find(p, classname, "info_dropped_flag");
  1336.         }
  1337.     }
  1338.  
  1339.     // If on team 2 switch meanings of flags
  1340.     if (self.team != TEAM_COLOR1 + 1) {
  1341.         p = flag1;
  1342.         flag1 = flag2;
  1343.         flag2 = p;
  1344.     }
  1345.  
  1346.     // Find if a player is carrying the flag(s)
  1347.     thief1 = world;
  1348.     thief2 = world;
  1349.  
  1350.     p = find(world, classname, "player");
  1351.     while (p != world) {
  1352.         if ((p.player_flag & ITEM_ENEMY_FLAG)) {
  1353.             if (p.team == self.team)
  1354.                 thief2 = p;
  1355.             else
  1356.                 thief1 = p;
  1357.         }
  1358.         p = find(p, classname, "player");
  1359.     }
  1360.  
  1361.     // Player's team flag status
  1362.     if (thief1 == world) {
  1363.         sprint(self, "Your flag is ");
  1364.         if (flag2 == world)
  1365.             sprint (self, " missing! ");
  1366.         else {
  1367.             if (flag1.cnt)
  1368.                 sprint(self, "in your base. ");
  1369.             else
  1370.                 sprint(self, "lying about. ");
  1371.         }            
  1372.     } else {
  1373.         sprint (self, thief1.netname);
  1374.         sprint (self, " has your flag. ");
  1375.     }
  1376.  
  1377.     // Enemy team flag status
  1378.     if (thief2 == world) {
  1379.         sprint(self, "The enemy flag is ");
  1380.         if (flag2 == world)
  1381.             sprint (self, "missing!\n");
  1382.         else {
  1383.             if (flag2.cnt)
  1384.                 sprint(self, "in their base.\n");
  1385.             else
  1386.                 sprint(self, "lying about.\n");
  1387.         }
  1388.     } else {
  1389.         if (self == thief2)
  1390.             sprint(self, "You have the enemy flag.\n");
  1391.         else {
  1392.             sprint (self, thief2.netname);
  1393.             sprint (self, " has the enemy flag.\n");
  1394.         }
  1395.     }
  1396. };
  1397.  
  1398.